package collection;

import java.util.Iterator;

public class ListMap<K, V> implements IMap<K,V>{

	private DLinkedList<Entry<K,V>> internalList = new DLinkedList<Entry<K,V>>();
	
	@Override
	public int size() 
	{
		return internalList.size();
	}

	@Override
	public boolean isEmpty() 
	{
		return internalList.isEmpty();
	}
	
	private DNode<Entry<K,V>> find(K key)
	{
		for (DNode<Entry<K,V>> entryNode : internalList)
		{
			if (entryNode.getElement().getKey().equals(key))
			{
				return entryNode;
			}
		}
		
		return null;
	}

	@Override
	public V get(K key)
	{
		DNode<Entry<K,V>> entryNode = find(key);
		
		if (entryNode != null)
		{
			return entryNode.getElement().getValue();
		}
		else
		{
			return null;
		}
	}

	@Override
	public void put(K key, V value) 
	{
		DNode<Entry<K,V>> entryNode = find(key);
		
		if (entryNode != null)
		{
			entryNode.getElement().setValue(value);
		}
		else
		{
			internalList.addLast(internalList.createNode(new Entry<K,V>(key, value)));
		}
	}

	@Override
	public V remove(K key) 
	{
		DNode<Entry<K,V>> entryNode = find(key);
		
		if (entryNode != null)
		{
			V retVal = entryNode.getElement().getValue();
			internalList.remove(entryNode);
			
			return retVal;
		}
		else
		{
			return null;
		}
	}

	@Override
	public Iterator<K> keys() 
	{
		final Iterator<Entry<K,V>> iter = internalList.elementsIterator();
		
		return new Iterator<K>(){

			@Override
			public boolean hasNext() 
			{
				return iter.hasNext();
			}

			@Override
			public K next() 
			{
				return iter.next().getKey();
			}

			@Override
			public void remove() 
			{
				throw new UnsupportedOperationException();
			}
			
		};
	}

	@Override
	public Iterator<V> values() 
	{
		final Iterator<Entry<K,V>> iter = internalList.elementsIterator();
		
		return new Iterator<V>(){

			@Override
			public boolean hasNext() 
			{
				return iter.hasNext();
			}

			@Override
			public V next() 
			{
				return iter.next().getValue();
			}

			@Override
			public void remove() 
			{
				throw new UnsupportedOperationException();
			}
			
		};
	}

	@Override
	public Iterator<Entry<K, V>> entries() 
	{
		final Iterator<Entry<K,V>> iter = internalList.elementsIterator();
		
		return new Iterator<Entry<K,V>>(){

			@Override
			public boolean hasNext() 
			{
				return iter.hasNext();
			}

			@Override
			public Entry<K,V> next() 
			{
				return iter.next();
			}

			@Override
			public void remove() 
			{
				throw new UnsupportedOperationException();
			}
			
		};
	}

	@Override
	public Iterator<Entry<K, V>> iterator() 
	{
		return entries();
	}
	
}
